<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>call</title>
  </head>
  <body></body>
  <script>
    function a() {
      console.log(this);
    }
    function b(arg) {
      console.log(arg);
    }
    var c = { name: 'call' };
    //a(); // window
    //a.call(); // window
    //a.call(b); // ƒ b(){}
    //a.call(c); // {name: "call"}

    var obj = {
      user: '哈哈哈',
      fn: function(arg, arg1) {
        console.log(this);
        console.log(this.user); //当前this指向obj,调用它的对象
        console.log(arg + '....' + arg1);
      }
    };
    var b1 = obj.fn;
    console.log(b1)
    b1.call(obj, 1, 2);
    console.log(b1.call) // ƒ call() { [native code] } 
    b1.call.call(obj, 1, 2); // 会报错 当前函数变化为call函数然后再变成obj.call
    //b1(); // undefined
    //obj.fn(); // 哈哈哈
    /*解释：var b1 = obj.fn时，this指向window*/
    //b1.call(obj); // 哈哈哈 call修改了this的指向 指向了obj
    //b1.call(obj, 1, 2); //哈哈哈 1....2
    b1.call(obj, 1, 2);
    //b1.apply(obj, [1, 2]); //apply跟call用法相同，但是apply第二个参数必须是一个数组
    //b1.call(null, 1, 2); // undefined 1....2 如果call和apply的第一个参数写的是null，那么this指向的是window对象
    //b1.bind(obj); // 不打印
    //console.log(b1.bind(obj)); // 返回一个修改后的函数
    /*
    ƒ (arg,arg1){
            console.log(this)
            console.log(this.user) //当前this指向obj,调用它的对象
            console.log(arg+'....'+arg1)
        }
    */
    //b1.bind(obj)(1, 2); // 哈哈哈 1....2

    function d() {
      console.log(this, 'd');
    }
    function e() {
      console.log(this,'b');
    }
    //d.call(e);
    /*
    ƒ e() {
      console.log(this,'b');
    } "d"
    */ 
    d.call.call(e,'hhhhh',1) //String{"hhhhh"} "b" 最终指向传入的这个参数 
    //d.call.call(e,false) // Boolean {false} "b" 
    //d.call.call(e,1)  // Number {1} "b"
  </script>
</html>
